/* rehash --- a decentralised hash<->hash store
   Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>

   This file is part of rehash.

   rehash is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or (at
   your option) any later version.

   rehash is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with rehash.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef _REHASH_REHASH_H
#define _REHASH_REHASH_H

#include <gnunet/gnunet_time_lib.h>

/* TODO: are response id's required?
   See GNUNET_DHT_*.
   TODO: replication level?  */.
GNUNET_NETWORK_STRUCT_BEGIN

/**
 * Message from client to rehash service to lookup hash->hash mappings
 */
struct REHASH_GetMessage
{
  /**
   * Header of type #GNUNET_MESSAGE_TYPE_REHASH_GET
   */
  struct GNUNET_MessageHeader header;
  /**
   * request / response relation
   */
  uint32_t request_id;
  uint32_t options; /* NBO, enum GNUNET_FS_SearchOptions */
  /**
   * Requested anonymity level, NBO
   */
  uint32_t anonymity_level;
  /**
   * Hash type to search with,
   * enum REHASH_Hash_Type in NBO.
   */
  uint32_t in_type;
  /**
   * Hash type to search for,
   * enum REHASH_Hash_Type in NBO.
   */
  uint32_t out_type;
  /**
   * Length of input hash, NBO
   */
  uint32_t input_length;
  /* Followed by input_length bytes */
};

/**
 * Message from rehash service to client to return hash->hash mappings
 */
struct REHASH_ResultMessage
{
  /**
   * Header of type #GNUNET_MESSAGE_TYPE_REHASH_RESULT
   */
  struct GNUNET_MessageHeader header;
  /**
   * When will this mapping expire?
   */
  struct GNUNET_TIME_AbsoluteNBO exp;
  /**
   * To which REHASH_GetMessage
   * does this answer correspond?
   */
  uint32_t request_id;
  /**
   * Length of output hash, in NBO
   */
  uint32_t output_length;
  /* Followed by output_length bytes */
};

/**
 * Message from client to rehash service to stop a hash->hash lookup
 * request
 */
struct REHASH_GetStopMessage
{
  /**
   * Header of type #GNUNET_MESSAGE_TYPE_REHASH_RESULT
   */
  struct GNUNET_MessageHeader header;
  /**
   * Which REHASH_GetMessage should be stopped?
   */
  uint32_t request_id;
};

/**
 * Message from client to rehash service to insert a hash->hash
 * mapping
 */
struct REHASH_PutMessage {
  struct GNUNET_MessageHeader header;
  struct GNUNET_TIME_AbsoluteNBO expiration_time;
  /** for cancelling (TODO for progress?) */
  uint32_t request_id;
  /** NBO */
  uint32_t anonymity_level;
  /** NBO */
  uint32_t content_priority;
  /** NBO */
  uint32_t replication_level;
  /**
   * Hash type to search with,
   * enum REHASH_Hash_Type in NBO.
   */
  uint32_t in_type;
  /**
   * Hash type to search for,
   * enum REHASH_Hash_Type in NBO.
   */
  uint32_t out_type;
  /**
   * Length of hash to search with, NBO
   */
  uint32_t input_length;
  /**
   * Length of hash to search for, NBO
   */
  uint32_t output_length;
  /* Followed by input_length bytes
     for the input hash, and output_length bytes
     for output hash */
};

enum REHASH_PutStatus
  {
    /* The rehash service considers this insertion
       to be completed. Don't pester rehash about
       it anymore. */
    REHASH_PUT_COMPLETED = 1 << 0,
    /* flags 1 << i with i >= 15 may be ignored
       if unrecognised.  Others must not. */
  };

/**
 * Message from rehash service to client
 * for status updates on a hash-hash insertion. */
struct REHASH_PutStatusMessage {
  /**
   * Type: #GNUNET_MESSAGE_TYPE_REHASH_PUT_DONE
   */
  struct GNUNET_MessageHeader header;
  /**
   * If REHASH_PUT_DONE is set,
   * the service now has forgotten about
   * this request.
   */
  uint32_t request_id GNUNET_PACKED;
  /** enum REHASH_PUT_STATUS,
      in network byte-order. */
  uint32_t flags GNUNET_PACKED;
};

GNUNET_NETWORK_STRUCT_END
#endif
